package com.zpdl.encryptionphoto;

import java.util.ArrayList;

import com.zpdl.encryptionphoto.R;
import android.app.ActionBar;
import android.app.Activity;
import android.app.Fragment;
import android.content.CursorLoader;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.text.TextUtils.TruncateAt;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.zpdl.api.util.Alog;

/**
 * Fragment used for managing interactions for and presentation of a navigation
 * drawer. See the <a href=
 * "https://developer.android.com/design/patterns/navigation-drawer.html#Interaction"
 * > design guidelines</a> for a complete explanation of the behaviors
 * implemented here.
 */
public class HpListNavigationDrawerFragment extends Fragment {

    /**
     * Remember the position of the selected item.
     */
    private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
    private static final String STATE_SELECTED_DIRECTORY = "selected_navigation_drawer_directory";

    /**
     * Per the design guidelines, you should show the drawer on launch until the
     * user manually expands it. This shared preference tracks this.
     */
    private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";

    /**
     * A pointer to the current callbacks instance (the Activity).
     */
    private NavigationDrawerCallbacks mCallbacks;

    /**
     * Helper component that ties the action bar to the navigation drawer.
     */
    private ActionBarDrawerToggle mDrawerToggle;

    private DrawerLayout mDrawerLayout;
    private ListView mDrawerListView;
    private View mFragmentContainerView;

    private int mCurrentSelectedPosition = 0;
    private boolean mFromSavedInstanceState;
    private boolean mUserLearnedDrawer;

    private ArrayList<String> mDirectoryList;

    public HpListNavigationDrawerFragment() {
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Alog.i("HpListNavigationDrawerFragment : onCreate");

        // Read in the flag indicating whether or not the user has demonstrated
        // awareness of the
        // drawer. See PREF_USER_LEARNED_DRAWER for details.
        SharedPreferences sp = PreferenceManager
                .getDefaultSharedPreferences(getActivity());
        mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);

        initDirectoryList();

        if (savedInstanceState != null) {
            mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
            if(mCurrentSelectedPosition > 0) {
                String savedDirectory = savedInstanceState.getString(STATE_SELECTED_DIRECTORY);
                if(!savedDirectory.equals(mDirectoryList.get(mCurrentSelectedPosition))) {
                    mCurrentSelectedPosition = 0;
                    for(int i = 1; i < mDirectoryList.size(); i++) {
                        if(savedDirectory.equals(mDirectoryList.get(i))) {
                            mCurrentSelectedPosition = i;
                            break;
                        }
                    }
                }
            }
            mFromSavedInstanceState = true;
        }

        // Select either the default item (0) or the last selected item.
//        selectItem(mCurrentSelectedPosition);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        Alog.i("HpListNavigationDrawerFragment : onActivityCreated");
        // Indicate that this fragment would like to influence the set of
        // actions in the action bar.
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        Alog.i("HpListNavigationDrawerFragment : onCreateView");
        mDrawerListView = (ListView) inflater.inflate(
                R.layout.hp_list_navigation_drawer_fragment, container, false);
        mDrawerListView
                .setOnItemClickListener(new AdapterView.OnItemClickListener() {
                    @Override
                    public void onItemClick(AdapterView<?> parent, View view,
                            int position, long id) {
                        selectItem(position);
                    }
                });

        HpListNavigationAdapter adapter = new HpListNavigationAdapter(getActionBar().getThemedContext(), mDirectoryList);
        mDrawerListView.setAdapter(adapter);
        mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);

        return mDrawerListView;
    }

    public boolean isDrawerOpen() {
        return mDrawerLayout != null
                && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
    }

    public String getDirectory(int position) {
        return mDirectoryList == null ? null : mDirectoryList.get(position);
    }

    public void refresh() {
        String title = mDirectoryList.get(0);
        mDirectoryList.clear();
        mDirectoryList.add(title);

        String[] column = {
                "distinct replace("+MediaStore.Images.Media.DATA+", "+ MediaStore.Images.Media.DISPLAY_NAME+", '')"
        };
        CursorLoader cursorLoader = new CursorLoader(getActionBar().getThemedContext(),
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column,
                null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();

        if(cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) {
                mDirectoryList.add(cursor.getString(0));
                cursor.moveToNext();
            }
        }
        ((HpListNavigationAdapter) mDrawerListView.getAdapter()).notifyDataSetChanged();
    }

    public boolean selectItem(String item) {
        for(int i = 0; i < mDirectoryList.size(); i++) {
            if(mDirectoryList.get(i).equals(item)) {
                selectItem(i);
                return true;
            }
        }
        return false;
    }

    public String getSelectItem() {
        return mDirectoryList.get(mCurrentSelectedPosition);
    }

    /**
     * Users of this fragment must call this method to set up the navigation
     * drawer interactions.
     *
     * @param fragmentId
     *            The android:id of this fragment in its activity's layout.
     * @param drawerLayout
     *            The DrawerLayout containing this fragment's UI.
     */
    public void setUp(int fragmentId, DrawerLayout drawerLayout) {
        mFragmentContainerView = getActivity().findViewById(fragmentId);
        mDrawerLayout = drawerLayout;

        // set a custom shadow that overlays the main content when the drawer
        // opens
        mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
                GravityCompat.START);
        // set up the drawer's list view with items and click listener

        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        actionBar.setHomeButtonEnabled(true);

        final int actionBarTitle = Resources.getSystem().getIdentifier("action_bar_title", "id", "android");
        final TextView title = (TextView)getActivity().getWindow().findViewById(actionBarTitle);
        if ( title != null ) {
            title.setEllipsize(TruncateAt.START);
        }

        // ActionBarDrawerToggle ties together the the proper interactions
        // between the navigation drawer and the action bar app icon.
        mDrawerToggle = new ActionBarDrawerToggle(getActivity(), /*
                                                                  * host
                                                                  * Activity
                                                                  */
        mDrawerLayout, /* DrawerLayout object */
        R.drawable.ic_drawer, /* nav drawer image to replace 'Up' caret */
        R.string.navigation_drawer_open, /*
                                          * "open drawer" description for
                                          * accessibility
                                          */
        R.string.navigation_drawer_close /*
                                          * "close drawer" description for
                                          * accessibility
                                          */
        ) {
            @Override
            public void onDrawerClosed(View drawerView) {
                super.onDrawerClosed(drawerView);
                if (!isAdded()) {
                    return;
                }

                getActivity().invalidateOptionsMenu(); // calls
                                                       // onPrepareOptionsMenu()
                Alog.e("onDrawerClosed");
            }

            @Override
            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                if (!isAdded()) {
                    return;
                }

                if (!mUserLearnedDrawer) {
                    // The user manually opened the drawer; store this flag to
                    // prevent auto-showing
                    // the navigation drawer automatically in the future.
                    mUserLearnedDrawer = true;
                    SharedPreferences sp = PreferenceManager
                            .getDefaultSharedPreferences(getActivity());
                    sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true)
                            .apply();
                }

                _checkDataSetChanged();
                getActivity().invalidateOptionsMenu(); // calls
                                                       // onPrepareOptionsMenu()
            }
        };

        // If the user hasn't 'learned' about the drawer, open it to introduce
        // them to the drawer,
        // per the navigation drawer design guidelines.
        if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
            mDrawerLayout.openDrawer(mFragmentContainerView);
        }

        // Defer code dependent on restoration of previous instance state.
        mDrawerLayout.post(new Runnable() {
            @Override
            public void run() {
                mDrawerToggle.syncState();
            }
        });

        mDrawerLayout.setDrawerListener(mDrawerToggle);
    }

    public void selectItem(int position) {
        mCurrentSelectedPosition = position;
        if (mDrawerListView != null) {
            mDrawerListView.setItemChecked(position, true);
        }
        if (mDrawerLayout != null) {
            mDrawerLayout.closeDrawer(mFragmentContainerView);
        }
        if (mCallbacks != null) {
            mCallbacks.onNavigationDrawerItemSelected(position, mDirectoryList.get(position));
        }
    }

    public void currentSelectedItem() {
        selectItem(mCurrentSelectedPosition);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        Alog.i("HpListNavigationDrawerFragment : onAttach");

        try {
            mCallbacks = (NavigationDrawerCallbacks) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(
                    "Activity must implement NavigationDrawerCallbacks.");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        Alog.i("HpListNavigationDrawerFragment : onDetach");

        mCallbacks = null;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
        outState.putString(STATE_SELECTED_DIRECTORY, mDirectoryList.get(mCurrentSelectedPosition));
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // Forward the new configuration the drawer toggle component.
        mDrawerToggle.onConfigurationChanged(newConfig);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // If the drawer is open, show the global app actions in the action bar.
        // See also
        // showGlobalContextActionBar, which controls the top-left area of the
        // action bar.
        if (mDrawerLayout != null && isDrawerOpen()) {
            inflater.inflate(R.menu.global, menu);
            showGlobalContextActionBar();
        }
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (mDrawerToggle.onOptionsItemSelected(item)) {
            return true;
        }

        if (item.getItemId() == R.id.action_example) {
            Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT)
                    .show();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * Per the navigation drawer design guidelines, updates the action bar to
     * show the global app 'context', rather than just what's in the current
     * screen.
     */
    private void showGlobalContextActionBar() {
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayShowTitleEnabled(true);
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        actionBar.setTitle(R.string.app_name);
    }

    private ActionBar getActionBar() {
        return getActivity().getActionBar();
    }

    private void initDirectoryList() {
        mDirectoryList = HpListNavigationAdapter.createArrayList(getActionBar().getThemedContext());

        String[] column = {
                "distinct replace("+MediaStore.Images.Media.DATA+", "+ MediaStore.Images.Media.DISPLAY_NAME+", '')"
        };
        CursorLoader cursorLoader = new CursorLoader(getActionBar().getThemedContext(),
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column,
                null, null, null);
        Cursor cursor = cursorLoader.loadInBackground();

        if(cursor.moveToFirst()) {
            while (!cursor.isAfterLast()) {
            	String data = cursor.getString(0);
            	if(data != null) {
            		mDirectoryList.add(data);
            	}
                cursor.moveToNext();
            }
        }
    }

    private Cursor _loadCursor() {
        String[] column = {
                "distinct replace("+MediaStore.Images.Media.DATA+", "+ MediaStore.Images.Media.DISPLAY_NAME+", '')"
        };
        CursorLoader cursorLoader = new CursorLoader(getActionBar().getThemedContext(),
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI, column,
                null, null, null);

        return cursorLoader.loadInBackground();
    }

    private void _checkDataSetChanged() {
        boolean dataSetChanged = false;
        ArrayList<String> al = new ArrayList<String>();
        
        Cursor c = _loadCursor();
        if(c.moveToFirst()) {
            while (!c.isAfterLast()) {
            	String data = c.getString(0);
            	if(data != null) {
            		al.add(data);
            	}
                c.moveToNext();
            }
        }

        if(al.size() + 1 == mDirectoryList.size()) {
        	for(int i = 0; i < al.size(); i++) {
            	if(!al.get(i).equals(mDirectoryList.get(i+1))) {
                    dataSetChanged = true;
                    break;
            	}
            }
        } else {
        	dataSetChanged = true;
        }

        if(dataSetChanged) {
            String title = mDirectoryList.get(0);
            mDirectoryList.clear();
            mDirectoryList.add(title);

            for(String data : al) {
            	mDirectoryList.add(data);
            }
            ((HpListNavigationAdapter) mDrawerListView.getAdapter()).notifyDataSetChanged();
        }
    }

    /**
     * Callbacks interface that all activities using this fragment must
     * implement.
     */
    public static interface NavigationDrawerCallbacks {
        /**
         * Called when an item in the navigation drawer is selected.
         */
        void onNavigationDrawerItemSelected(int position, String directory);
    }
}
